package com.zj.controller;

import com.zj.GeneratorApp;
import com.zj.bean.VueConfig;
import com.zj.job.CodeSnippetJob;
import com.zj.processors.TemplateProcessor;
import com.zj.util.JsonUtil;
import de.felixroske.jfxsupport.FXMLController;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.stage.FileChooser;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

@FXMLController
public class VueCtl implements Initializable {

    public TextField projectNameInpt;
    public TextField userNameInpt;
    public TextField jarPathInpt;
    public Button startBtn;
    public TextArea logArea;
    public FileChooser jarChooser;
    public GridPane gridPane;
    public AnchorPane topPane;
    public TextField passwordInpt;
    public TextField jdbcUrlInpt;
    public TextArea tableStrInpt;

    public static Map<String, File> PROJECT_MAP = new HashMap<>();
    public ComboBox navContext;
    public ComboBox templateSelect;
    public TextField moduleNameInpt;
    private File currentConfigFile;

    private static Map<String,TemplateProcessor> processorMap;

    @Autowired
    private ApplicationContext applicationContext;
    
    public void log(final String log){
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                logArea.appendText(log);
                logArea.appendText("\n");
            }
        });
    }
    public void cleanLog(){
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                logArea.setText("");
            }
        });
    }

    public void alert(String msg){
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("提示");
        alert.setHeaderText(msg);
        alert.showAndWait();
    }

    public void openChooseJar(ActionEvent actionEvent){
        if (jarChooser == null) {
            jarChooser=new FileChooser();
        }
        jarChooser.setTitle("选择Jar");
        File jarFile=jarChooser.showOpenDialog(GeneratorApp.primaryStage);
        if (jarFile != null) {
            jarPathInpt.setText(jarFile.getAbsolutePath());
            log(jarFile.getAbsolutePath());
        }
    }


    public void startCrawler(ActionEvent actionEvent) {
        String projectName=projectNameInpt.getText();
        String userName=userNameInpt.getText();
        String jarPath=jarPathInpt.getText();
        String jdbcUrl=jdbcUrlInpt.getText();
        String moduleName=moduleNameInpt.getText();

        String password=passwordInpt.getText();
        String tableStr=tableStrInpt.getText();
        String template=templateSelect.getSelectionModel().getSelectedItem().toString();

        if (StringUtils.isEmpty(password)) {
            alert("请输入密码!");
            return;
        }
        if (StringUtils.isEmpty(projectName)) {
            alert("请输入项目名称!");
            return;
        }
        if (StringUtils.isEmpty(projectName)) {
            alert("请输入项目!");
            return;
        }

        if (StringUtils.isEmpty(projectName)) {
            alert("请输入项目!");
            return;
        }

        if (StringUtils.isEmpty(userName)) {
            alert("请输入用户名!");
            return;
        }

        if (StringUtils.isEmpty(jarPath)) {
            alert("请输入Jar路径!");
            return;
        }
        if (StringUtils.isEmpty(template)) {
            alert("请选择模板!");
            return;
        }



//        if (StringUtils.isEmpty(apiPath)) {
//            alert("请选择工作目录!");
//            return;
//        }
        if (StringUtils.isEmpty(tableStr)) {
            alert("请输入表名, 以空格隔开!");
            return;
        }
        if (tableStr.contains(",")) {
            alert("请输入表名, 以空格隔开!");
            return;
        }

        log("参数验证完成。。。");
        final VueConfig vueConfig=new VueConfig();
        vueConfig.setJdbcUrl(jdbcUrl);
        vueConfig.setUserName(userName);
        vueConfig.setPassword(password);
        vueConfig.setProjectName(projectName);
        vueConfig.setConnectorPath(jarPath);
        vueConfig.setTableStr(tableStr);
        vueConfig.setTemplateName(template);
        vueConfig.setLastUseTime(System.currentTimeMillis());
        vueConfig.setModuleName(moduleName);
        cleanLog();
        log(JsonUtil.obj2String(vueConfig));


        File configFile=currentConfigFile;
        try {
            FileUtils.writeStringToFile(configFile, JsonUtil.obj2String(vueConfig),"utf-8");
        } catch (IOException e) {
            e.printStackTrace();
        }


        new CodeSnippetJob(vueConfig,this,processorMap.get(template)).start();

    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        processorMap =applicationContext.getBeansOfType(TemplateProcessor.class);

//        Color color=Color.web("#4169E1");
//        Color color=Color.rgb(0,67,151);
//
//        gridPane.setBackground(new Background(new BackgroundFill(color,null,null)));
//        topPane.setBackground(new Background(new BackgroundFill(color,null,null)));

//        System.out.println("initialize");

        File confDir = new File("./vue_config");

        if(!confDir.exists()){
            System.out.println("no config directory!");
            return;
        }

        File[] fileList = confDir.listFiles();
        if(fileList==null || fileList.length == 0){
            System.out.println("no config file!");
            return;
        }
        //默认打开最近打开的
        int lastUseIndex=0;
        long lastTime=0;
        for (File configFile : fileList) {
            try {
                String json = FileUtils.readFileToString(configFile, "utf-8");
                VueConfig config = JsonUtil.toObject(json, VueConfig.class);
                PROJECT_MAP.put(config.getProjectName(), configFile);
                navContext.getItems().add(config.getProjectName());
                if (config.getLastUseTime() != null && config.getLastUseTime() > lastTime) {
                    lastTime=config.getLastUseTime();
                    lastUseIndex=navContext.getItems().size()-1;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        ChangeProject changeListener= new ChangeProject();
        navContext.setOnAction(changeListener);
        if (PROJECT_MAP.size() > 0) {
            navContext.getSelectionModel().select(lastUseIndex);
            changeListener.handle(null);
        }

        for(String templateProcessor:processorMap.keySet()){
            templateSelect.getItems().add(templateProcessor);
        }
    }

    public void setInputValue(File configFile){
        String json = null;
        try {
            json = FileUtils.readFileToString(configFile, "utf-8");
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        VueConfig config = JsonUtil.toObject(json, VueConfig.class);
        if (config != null) {
            jarPathInpt.setText(config.getConnectorPath());
            jdbcUrlInpt.setText(config.getJdbcUrl());
            moduleNameInpt.setText(config.getModuleName());
            userNameInpt.setText(config.getUserName());
            projectNameInpt.setText(config.getProjectName());
            passwordInpt.setText(config.getPassword());
            tableStrInpt.setText(config.getTableStr());
            templateSelect.getSelectionModel().select(config.getTemplateName());
        }
    }

    class ChangeProject<ActionEvent> implements EventHandler {

        @Override
        public void handle(Event event) {
            String key= navContext.getSelectionModel().getSelectedItem().toString();
            currentConfigFile=PROJECT_MAP.get(key);
            setInputValue(PROJECT_MAP.get(key));
        }
    }

}
